from rest_framework import serializers
from django_redis import get_redis_connection
from redis import RedisError
import logging


from users.models import User


#获取在配置文件中定义的loggre,用来记录日志
logger = logging.getLogger('django')





class ImageCodeCheckSerializer(serializers.Serializer):
    """校验图形验证码序列化器"""
    #声明规则验证
    image_code=serializers.CharField(min_length=4,max_length=4)
    #UUIDField 专门用于校验uuid格式类型的字符串
    image_code_id=serializers.UUIDField()

    def validate(self,attrs):
        #接受校验数据
        image_code=attrs['image_code']
        image_code_id=attrs['image_code_id']
        #从redis中获取真实的图片验证码
        redis_conn = get_redis_connection('verify_codes')
        real_image_code_text = redis_conn.get('img_%s' % image_code_id)

        image_code_id = attrs['image_code_id']
        image_code = attrs['image_code']



        if not real_image_code_text:
            raise serializers.ValidationError('图片验证码无效')


        #如果根据当前的image_code_id获取不到值
        if not real_image_code_text:
            raise serializers.ValidationError('图片验证码无效')

        #图形验证码只能使用一次，所以接下来，需要删除验证码
        try:
            redis_conn.delete('img_%s' % image_code_id)
        except RedisError as e:
            logger.error(e)

        #在python中从redis中拿到的数据都是bytes类型
        real_image_code_text = real_image_code_text.decode()

        #比较图形验证码
        if real_image_code_text.lower() != image_code.lower():
            raise serializers.ValidationError('图片验证码错误')


        # 2.检查是否在60秒内有发送记录
        #在序列化器中要获取视图类中数据,格式：self.context['view'].kwargs['变量名']
        mobile = self.context['view'].kwargs.get('mobile')
        if mobile:
            send_flag=redis_conn.get('send_flag_%s' % mobile)
            #如果redis中有这个数据，则表示60秒内发送过短信
            if send_flag:
                raise serializers.ValidationError("请求次数过于频繁")
        return attrs

class CheckSMSCodeTokenSerializer(serializers.Serializer):
    #声明字段
    access_token = serializers.CharField(label="发送短信的临时票据access_token",required=True)

    def validate(self, attrs):
        access_token = attrs["access_token"]
        #校验access_token
        mobile = User.check_send_sms_code_token(access_token)
        if mobile is None:
            raise serializers.ValidationError('用户不存在')

        #校验当前手机号是否在60s内发送短信
        redis_conn = get_redis_connection('verify_codes')
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        # 如果redis中有这个数据，则表示60秒内发送过短信
        if send_flag:
            raise serializers.ValidationError("请求次数过于频繁")
        #把手机号作为序列化器的属性，可以通过序列化器提取出来
        self.mobile = mobile
        return attrs